package com.aboo.web.common.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Properties;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.MDC;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

import com.aboo.web.common.domain.ShiroUser;

/**
 * 拦截器，进行日志记录
 * @author 娄安
 * @date 2013-6-3
 */
@Aspect
public class LoggerAspect {
	
	private static final Logger logger = LoggerFactory.getLogger(LoggerAspect.class);
	
	@Autowired
	@Qualifier("moduleForLog")
	private Properties moduleForLog;
	
	@Before("execution (* com.ruijian.jspub.web.*.service.*.*(..))")
	public void doBefore(JoinPoint jp) {
		String className = jp.getTarget().getClass().getName();
		String methodName = jp.getSignature().getName();
		logger.info("Begining method: " + className + "." + methodName);
    }
	
	@After("execution (* com.ruijian.jspub.web.*.service.*.*(..))")
	public void doAfter(JoinPoint jp) {
		String className = jp.getTarget().getClass().getName();
		String methodName = jp.getSignature().getName();
		logger.info("Ending method: " + className + "." + methodName);
    }

	@AfterThrowing(pointcut="execution (* com.ruijian.jspub.web.*.service.*.*(..))", throwing="ex")
    public void doThrowing(JoinPoint jp, Throwable ex) {
		String className = jp.getTarget().getClass().getName();
		String methodName = jp.getSignature().getName();
		
		Subject currentUser = SecurityUtils.getSubject();
		ShiroUser shiroUser = (ShiroUser)currentUser.getPrincipal();
		String username = "";
		if (currentUser != null && shiroUser != null) {
			username = shiroUser.getUserName();
		}
		MDC.put("username", username);
		MDC.put("invokeMethod", className + "." + methodName);
		MDC.put("module", getModuleName(className));
		StringWriter sw = new StringWriter();
		PrintWriter p = new PrintWriter(sw);
		ex.printStackTrace(p);
		MDC.put("stackTrace", sw.toString());
		logger.error(ex.getMessage(), ex);
    }

	//方法执行的前后调用，暂时不需要
	/*
	@Around("execution (* com.ruijian.jspub.web.*.service.*.*(..))")
	public Object around(ProceedingJoinPoint point) throws Throwable {
		String className = point.getTarget().getClass().getName();
		String methodName = point.getSignature().getName();
		logger.info("Around method: " + className + "." + methodName);
		Object obj = null;
		try {
			obj = point.proceed();
		} catch (Throwable e) {
			throw e;
		}
		
		return obj;
	}
	*/

	/**
	 * 根据package路径获取模块名称
	 * @author 娄安
	 * @param className
	 * @return
	 */
	private String getModuleName(String className) {
		String module = "other";
		
		if (StringUtils.isNotEmpty(className)) {
			if (className.indexOf("com.ruijian.jspub.web.authority") != -1)
				return moduleForLog.getProperty("com.ruijian.jspub.web.authority");
			if (className.indexOf("com.ruijian.jspub.web.foundation") != -1)
				return moduleForLog.getProperty("com.ruijian.jspub.web.foundation");
		}
		
		return module;
	}
	
}
